/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sd_proj1.monSolution;

import java.util.TreeMap;
import sd_proj1.interfaces.*;

/**
 *
 * @author PedroEee
 */
public class EstadoGeral implements IntArtesaosFifo, IntClientesFifo, IntDonaFifo {

	private MemFIFO fifo = new MemFIFO(1000);
	private int nReqDona = 0;
	private int nPecasTransporte = 0;
	private boolean allCraftsDead = false;
	private TreeMap map;
	private Mensagem mlog;
	FifoNode object = new FifoNode();
	FifoNode objectahead = new FifoNode();

	public EstadoGeral(TreeMap map) {
		this.map = map;
	}

	public synchronized void addRequestCliente(int ClienteId) {
		System.out.println("O " + ClienteId + " CHAMA A SENHORA DONA!");
		fifo.write(new FifoNode(ClienteId, 'C'));
		nReqDona = nReqDona + 1;
		System.out.println("addRequestCliente - nReqDona+");
		notifyAll();
		System.out.println("addRequestCliente - notifyAll");
	}

	public synchronized void emptyRequest() {
		fifo.write(new FifoNode('E'));
		nReqDona = nReqDona + 1;
		notifyAll();
		System.out.println("emptyRequest - nReqDona+");
	}

	public synchronized void primeMaterialsNeededWN() {
		fifo.write(new FifoNode('P'));
		nReqDona = nReqDona + 1;
		notifyAll();
		mlog = new Mensagem();
		mlog.setShopStat(-1, -1, '0', 'T');
		map.put(Relogio.getInstance().getValue(), mlog);
		System.out.println("ENTROU NO primeMaterialsNeedesWN");
	}

	public synchronized void batchReadyForTransferWN(int np) {
		this.nPecasTransporte = np;
		fifo.write(new FifoNode('G'));
		nReqDona = nReqDona + 1;
		notifyAll();
		mlog = new Mensagem();
		mlog.setShopStat(-1, -1, 'T', '0');
		map.put(Relogio.getInstance().getValue(), mlog);
		System.out.println("ENTROU NO primeMaterialsNeedesWN");
	}

	/**
	 * O artesão notifica a dona de que estão em falta matérias primas para trabalhar (originada pelo artesão).
	 */
	public synchronized void primeMaterialsNeeded(int craftsmanId) {
		fifo.write(new FifoNode('P'));
		nReqDona = nReqDona + 1;
		notifyAll();
		mlog = new Mensagem();
		mlog.setShopStat(-1, -1, '0', 'T');
		mlog.setStatCraft(Mensagem.craftStat.CTTE, 0, craftsmanId);
		map.put(Relogio.getInstance().getValue(), mlog);
		System.out.println("primeMaterialsNeeded - CONTACTING THE ENTEPRENEUR");
	}

	/**
	 * O artesão notifica a dona que um carregamento de produtos está pronto para ser levado (originada pelo artesão).
	 */
	public synchronized void batchReadyForTransfer(int craftsmanId) {
		fifo.write(new FifoNode('G'));
		nReqDona = nReqDona + 1;
		notifyAll();

		mlog = new Mensagem();
		mlog.setShopStat(-1, -1, 'T', '0');
		mlog.setStatCraft(Mensagem.craftStat.CTTE, 0, craftsmanId);
		map.put(Relogio.getInstance().getValue(), mlog);

		System.out.println("batchReadyForTransfer - vem buscar " + nPecasTransporte + " peças, caralho!");
	}

	public synchronized FifoNode readRequest() {

		System.out.println("readRequest");
		System.out.println("readRequest - nReqDona: " + nReqDona);
		if (nReqDona == 0) {
			try {
				System.out.println("readRequest em wait");
				wait();
			} catch (Exception e) {
			}
		}
		
		object = (FifoNode) fifo.read();
		nReqDona = nReqDona - 1;
		if (nReqDona != 0) {
			objectahead = (FifoNode) fifo.peek();
			System.out.println("Object ahead " + objectahead.appraiseSit());
		}

		if (object.appraiseSit() == 'P' && nReqDona != 0) {
			if (objectahead.appraiseSit() == 'C') {
				System.out.println("Objecto inicial P e mais pedidos");
				primeMaterialsNeededWN();
			}
		} else if (object.appraiseSit() == 'G' && nReqDona != 0) {
			if (objectahead.appraiseSit() == 'C') {
				System.out.println("Objecto inicial G e mais pedidos");
				batchReadyForTransferWN(nPecasTransporte);
			}
		}

		return (object);
	}

	public int getnPecasTransporte() {
		return nPecasTransporte;
	}

	public void setnPecasTransporte(int nPecasTransporte) {
		this.nPecasTransporte = nPecasTransporte;
	}

	public boolean isAllCraftsDead() {
		return allCraftsDead;
	}

	public void setAllCraftsDead(boolean allCraftsDead) {
		this.allCraftsDead = allCraftsDead;
	}
}
